<template>
  <div class="hello">
    <h1>{{ msg }} - {{ a }} - {{ b }}</h1>
    <button @click="change">发射</button>
  </div>
</template>

<script lang="ts" setup>
import { inject } from "vue";
import { nameKey } from "@/types/index";
import { ageKey, userKey } from "../types/index";

// props类型声明：
// 1. 写法和普通的js声明props写法一样：运行时声明，它实际上运用了ts的类型推导功能，根据props的类型约束，推导prop类型。
// const props = defineProps({
//   msg: String,
//   a: Number,
//   b: {
//     type: Number,
//     default: 0,
//     required: true,
//   },
// });

// 2. 通过泛型添加约束: 这种写法，是利用ts的语法规则添加类型约束。
// const props = defineProps<{
//   msg: string;
//   a?: number;
//   b?: number;
// }>();

// 3. 通过withDefaults给这些Props设置默认值
interface IProps {
  msg?: string;
  a?: number;
  b?: number;
}
const defaultsProps = withDefaults(defineProps<IProps>(), {
  msg: "小明",
  a: 100,
  b: 200,
});

// emits类型声明
// 1. 传统写法：无需明确指定函数类型，让ts自行推断
// const emits = defineEmits(["setnum"]);
// const change = () => {
//   emits("setnum", 100);
// };

// 2. 手动约束每个自定义事件的类型
const emits = defineEmits<{
  (e: "setnum", data: number): void;
}>();
const change = () => {
  emits("setnum", 200);
};

const myname = inject<string>(nameKey);
const myage = inject(ageKey);
const myuser = inject(userKey);
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="less">
h3 {
  margin: 40px 0 0;
}
ul {
  list-style-type: none;
  padding: 0;
}
li {
  display: inline-block;
  margin: 0 10px;
}
a {
  color: #42b983;
}
</style>
